package com.autumn.juc.jmm;

/**
 *
 */
public class ReOrderTest {
    public static volatile int x = 0, y = 0;
    public static volatile int a = 0, b = 0;

    public static void main(String[] args) throws InterruptedException {
        int i = 0;
        while (true) {
            i++;
            x = 0;
            y = 0;
            a = 0;
            b = 0;

            /**
             * x,y: 0,0、0,1、1,0、1,1
             * 不使用volatile修饰时，因为存在指令重排序，因此也会出现 0,0 的结果
             * 使用stareLoad内存屏障可以禁止指令重排序，在两行代码中间加上内存屏障，当加载后方代码时，前方数据必须可见
             * 禁止指令重排序即保证有序性又保证可见性
             */
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    shortWait(20000);
                    a = 1;//volatile写
                    //Java层面的storeLoad使用volatile
                    //UnsafeFactory.getUnsafe().storeFence();//JVM层面的内存屏障，不会去使用
                    x = b;//volatile读
                }
            });

            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    b = 1;
                    //UnsafeFactory.getUnsafe().storeFence();//JVM层面的内存屏障，不会去使用
                    y = a;
                }
            });

            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();

            System.out.println("第" + i + "次（" + x + "," + y + ")");
            if (x == 0 && y == 0) {
                break;
            }
        }
    }

    public static void shortWait(long interval) {
        long start = System.nanoTime();
        long end;
        do {
            end = System.nanoTime();
        } while (start + interval >= end);
    }
}
